#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#define MAX_CLIENTS 10
#define BUFFER_SIZE 1024
int main()
{
    int fd[MAX_CLIENTS] = {0};
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1)
    {
        std::cerr << "Socket error: " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    sockaddr_in addr;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    if (bind(sockfd, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr)) == -1)
    {
        std::cerr << "Bind error: " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    if (listen(sockfd, 10) == -1)
    {
        std::cerr << "Listen error: " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    char buffer[BUFFER_SIZE] = {0};
    while (true)
    {
        fd_set setfd;
        FD_ZERO(&setfd);
        FD_SET(sockfd, &setfd);

        int maxFD = sockfd;
        for (int i = 0; i < MAX_CLIENTS; i++)
        {
            if (fd[i] > 0)
            {
                FD_SET(fd[i], &setfd);
                if (fd[i] > maxFD)
                {
                    maxFD = fd[i];
                }
            }
        }

        int activity = select(maxFD + 1, &setfd, NULL, NULL, NULL);
        if (activity < 0)
        {
            std::cerr << "Select error: " << strerror(errno) << std::endl;
            continue;
        }

        if (FD_ISSET(sockfd, &setfd))
        {
            int connfd = accept(sockfd, NULL, NULL);
            if (connfd == -1)
            {
                std::cerr << "Accept error: " << strerror(errno) << std::endl;
                continue;
            }

            int i;
            for (i = 0; i < MAX_CLIENTS; i++)
            {
                if (fd[i] == 0)
                {
                    fd[i] = connfd;
                    std::cout << "New connection, socket fd is " << connfd << std::endl;
                    break;
                }
            }
            if (i == MAX_CLIENTS)
            {
                std::cout << "Too many connections" << std::endl;
                close(connfd);
            }
        }

        for (int i = 0; i < MAX_CLIENTS; i++)
        {
            if (fd[i] > 0 && FD_ISSET(fd[i], &setfd))
            {
                memset(buffer, 0, BUFFER_SIZE);
                int readBytes = read(fd[i], buffer, BUFFER_SIZE - 1);
                if (readBytes > 0)
                {
                    std::cout << "Server received from client " << i << ": " << buffer;
                }
                else if (readBytes == 0)
                {
                    std::cout << "Client " << i << " disconnected" << std::endl;
                    close(fd[i]);
                    fd[i] = 0;
                }
                else
                {
                    std::cerr << "Read error: " << strerror(errno) << std::endl;
                    close(fd[i]);
                    fd[i] = 0;
                }
            }
        }
    }
    return EXIT_SUCCESS;
}
